<?php

namespace App\Service\Message\v1_0_4;

use App\Cache\RedisKey;
use App\Constants\AccostBusinesswomen;
use App\Model\CloseFriend;
use App\Model\Setting\SettingAppHidden;
use App\Model\User;
use App\Model\UserProfile;
use App\Model\UserRecommand;
use App\Service\BaseService;
use App\Service\ServiceTrait\AccostTrait;
use App\Service\ServiceTrait\GetUserInfoTrait;
use Hyperf\Redis\Redis;
use RedisException;

/**
 * 一键搭讪 - 推荐用户
 */
class RecUserListService extends BaseService
{
    use GetUserInfoTrait, AccostTrait;

    const ERROR_CODE = 0;

    /**
     * @var int
     */
    private $actionUserId;

    /**
     * @var Redis|mixed
     */
    private $redis;

    /**
     * 用户的key
     * @var string
     */
    private $key;

    /**
     * 锁定的用户key
     * @var string
     */
    private $lockKey;

    /**
     * 用户打招呼的key
     * @var string
     */
    private $numKey;

    /**
     * @return array[]
     * @throws RedisException
     */
    public function handle(): array
    {
        $return = [];

        $this->actionUserId = $this->userId;

        if (!$this->actionUserId) {
            log_info(__CLASS__."===actionUserId为空===".$this->actionUserId);
            return [];
        }

        //获取缓存的key和协程redis客户端对象
        $this->getRedis();

        //判断缓存
        if (!$this->checkCacheCondition()) {
            return $this->setError(self::ERROR_CODE, '搭讪较快，休息' . AccostBusinesswomen::LOCK_TIME . '分钟后再试吧～');
        }

        //用户信息不存在或者用户等于男性 直接返回
        $profile = $this->getUserInfo($this->actionUserId);
        if (!$profile || $profile->gender == 1) {
            return $return;
        }

        //获取推荐的用户 如果没有 返回报错信息
        $userIds = $this->recommend(3, 1);
        if (empty($userIds)) {
            return $this->setError(self::ERROR_CODE, '搭讪太多啦，先休息一会吧～');
        }

        //先获取用户的信息和im信息 然后循环组装数据
        $users = UserProfile::getUsersProfile($userIds);
        $imAccounts = User::getImAccounts($userIds);
        array_walk($users, function ($one) use ($imAccounts, &$return) {
            $item = UserProfile::buildRecItem($one, $imAccounts, 100);
            $return['list'][] = $item;
        });

        //添加记录
        $this->addRecord($this->userId, $userIds);

        return $return;
    }

    /**
     * 获取推荐
     * @param $number
     * @param int $getGender
     * @return array
     * @throws RedisException
     */
    private function recommend($number, int $getGender = -1): array
    {
        if (!$this->actionUserId) {
            return [];
        }

        $userRecommendModel = new UserRecommand();

        $recUserIds = $this->getUserRecommendData();

        $role = $getGender == 1 ? UserProfile::ROLE_USER : UserProfile::ROLE_HOST;

        //获取最新的用户
//        $recUsers = (new UserProfile)->getNewUsersV2($role, $getGender);
        $recUsers = $this->getNewRecommendUser($role, $getGender);
        if (empty($recUsers)) {
            return [];
        }

        //排除密友
        $recUsers = array_diff($recUsers, CloseFriend::getFrdList($this->actionUserId));

        // 排除渠道屏蔽用户
        $excludeUsers = $this->getExcludeUsers();
        if (count($excludeUsers)) {
            $recUsers = array_diff($recUsers, $excludeUsers);
        }

        $recUsers = array_values(array_diff($recUsers, array_merge($recUserIds, [$this->actionUserId])));
        $result = array_slice($recUsers, 0, $number);
        if (empty($result)) {
            return [];
        }

        return $result;
    }


    /**
     * @param $role
     * @param $gender
     * @return array
     * @throws RedisException
     */
    private function getNewRecommendUser($role, $gender): array
    {
        $onlineData = $this->redis->sMembers(RedisKey::userRecommendNewUserKey($role, $gender, 1)) ?? [];
        $noOnlineData = $this->redis->sMembers(RedisKey::userRecommendNewUserKey($role, $gender, 0)) ?? [];
        rsort($onlineData);
        rsort($noOnlineData);

        return array_unique(array_merge($onlineData, $noOnlineData));
    }


    /**
     * 添加数据
     * @param $userIds
     * @return void
     * @throws RedisException
     */
    private function addRecord($actionUserId, $userIds)
    {

        //添加记录
        UserRecommand::create([
            'user_id' => $actionUserId,
            'rec_user_ids' => json_encode($userIds),
        ]);

        //添加推荐列表
//        $this->redis->sAddArray($this->key, $userIds);
//
//        $script1 = <<<lua
//            local numStr = redis.call('exists',KEYS[1])
//            if numStr == 1 then
//                redis.call('incrBy',KEYS[1],ARGV[1])
//            else
//                redis.call('incrBy',KEYS[1],ARGV[1])
//                redis.call('Expire',KEYS[1],ARGV[2])
//            end
//
//            local totalNum = tonumber(redis.call('get',KEYS[1]))
//            if totalNum >= tonumber(ARGV[3]) then
//                redis.call('set',KEYS[2],"1")
//                redis.call('Expire',KEYS[2],ARGV[4])
//            end
//        lua;
//
//        //执行数量和是否锁定逻辑
//        $this->redis->eval($script1, [
//            $this->numKey,//搭讪数量的key
//            $this->lockKey,//锁定的key
//            count($userIds),//这次推荐有多少人
//            self::CONDITION_TIME * 60,//搭讪数量的key的时间(分钟)
//            self::CONDITION_NUMBER,//搭讪数量的最大值（达到这个值锁定）
//            self::LOCK_TIME * 60//搭讪锁定的时间(分钟)
//        ], 2);

    }
}
